package com.catazzz.springbootstudy.common.security;

import com.catazzz.springbootstudy.common.exception.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @作者: Tao
 * @日期: 2025/1/8
 * @时间: 09:51
 * @描述: 自定义认证成功处理类 <br><pre>
 *          继承自SavedRequestAwareAuthenticationSuccessHandler,用于在用户成功认证后执行特定的逻辑处理
 */
//@Component
public class CustomerAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    /**
     * 认证成功后的处理方法
     * 根据请求类型（Ajax请求或普通请求）来决定响应的内容类型和具体内容
     *
     * @param request HttpServletRequest对象，用于获取请求信息
     * @param response HttpServletResponse对象，用于设置响应内容
     * @param authentication Authentication对象，包含用户认证信息
     * @throws ServletException 如果出现Servlet相关的异常
     * @throws IOException 如果出现IO相关的异常
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        // 设置字符编码为UTF-8
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        // 判断是否为Ajax请求
        if (isAjaxRequest(request)) {
            // 是Ajax请求，则返回JSON格式的成功信息
            response.getWriter().write(new ObjectMapper().writeValueAsString(Result.success()));
        } else {
            // 不是Ajax请求，设置响应内容类型为HTML，并调用父类的处理方法
            response.setContentType(MediaType.TEXT_HTML_VALUE);
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }

    /**
     * 判断请求是否为Ajax请求
     * 通过检查请求头中的'X-Requested-With'来确定请求类型
     *
     * @param request HttpServletRequest对象，用于获取请求头信息
     * @return boolean 如果是Ajax请求返回true，否则返回false
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        // 获取请求头中的'X-Requested-With'字段值
        String requestType = request.getHeader("X-Requested-With");
        // 判断请求类型是否为'XMLHttpRequest'
        return "XMLHttpRequest".equals(requestType);
    }
}

